﻿using System.Linq;
using AutoMapper;
using CH.FourBoards.LagerWalti.Business.Core;
using CH.FourBoards.LagerWalti.Business.Warehouse;
using CH.FourBoards.LagerWalti.Service.DTOs.MasterData;
using CH.FourBoards.LagerWalti.Service.DTOs.Warehouse;
using CH.FourBoards.LagerWalti.Service.Mapping;

namespace CH.FourBoards.LagerWalti.Service.Services
{
    public class WarehouseService
    {
        public WarehouseService()
        {
            new MasterDataMapper().Register();
        }

        public InventoryCatalog ListAvailableInventory()
        {
            return ListInventory(1, null);
        }

        public InventoryCatalog ListOutOfStock()
        {
            return ListInventory(null, 0);
        }

        public InventoryCatalog ListInventory()
        {
            return ListInventory(null, null);
        }

        private InventoryCatalog ListInventory(int? minStock, int? maxStock)
        {
            // load ProductDTOs
            var products = new ProductManager().ListProducts().ToList();

            // query stock and add to catalog
            var wm = new WarehouseManager();
            var ret = new InventoryCatalog();
            foreach (var product in products) {

                // query stock 
                var item = new InventoryItem { ProductId = product.Id, Stock = wm.GetStock(product) };

                // check conditions
                if (!IsWithin(minStock, maxStock, item.Stock)) {
                    continue;
                }

                // add to catalog
                ret.Items.Add(item);
                ret.Products.Add(Mapper.Map<ProductDTO>(product));
            }

            // add categories
            var categories = products.Select(p => p.Category).Distinct();
            ret.Categories = categories.Select(Mapper.Map<CategoryDTO>).ToList();

            return ret;
        }

        private bool IsWithin(int? min, int? max, int value)
        {
            if (min.HasValue && (value < min.Value)) {
                return false;
            }
            if (max.HasValue && (value > max.Value)) {
                return false;
            }
            return true;
        }

    }
}
